home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / quicktime text / qttext / application files / comapplication.c next >
Encoding:
Text File  |  2000-09-28  |  14.6 KB  |  537 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for QuickTime Music Architecture sample.
  6. //                This file is used for BOTH MacOS and Windows.
  7. //
  8. //    Written by:    Tim Monroe
  9. //                Based (heavily!) on the MovieShell code written by Apple DTS.
  10. //
  11. //    Copyright:    © 1994-1997 by Apple Computer, Inc., all rights reserved.
  12. //
  13. //    Change History (most recent first):
  14. //
  15. //       <13>         02/03/99    rtm        removed "\p" escape sequences from strings
  16. //       <12>         12/16/98    rtm        removed all QTVR API calls, so we can remove QTVR.lib from project
  17. //       <11>         04/07/98    rtm        begun adding text support
  18. //       <10>         10/23/97    rtm        moved InitializeQTVR to InitApplication, TerminateQTVR to StopApplication
  19. //       <9>         10/13/97    rtm        reworked HandleApplicationMenu to use menu identifiers
  20. //       <8>         09/11/97    rtm        merged MacApplication.c and WinApplication.c into ComApplication.c
  21. //       <7>         08/21/97    rtm        first file for Windows; based on MacApplication.c for Mac sample code
  22. //       <6>         06/04/97    rtm        removed call to QTVRUtils_IsQTVRMovie in InitApplicationWindowObject
  23. //       <5>         02/06/97    rtm        fixed window resizing code
  24. //       <4>         12/05/96    rtm        added hooks into MacFramework.c: StopApplication, InitApplicationWindowObject
  25. //       <3>         12/02/96    rtm        added cursor updating to DoIdle
  26. //       <2>         11/27/96    rtm        conversion to personal coding style; added preliminary QTVR support
  27. //       <1>         12/21/94    khs        first file
  28. //       
  29. //////////
  30.  
  31. // header files
  32. #include "ComApplication.h"
  33. #include "QTText.h"
  34.  
  35. // global variables for Macintosh code
  36. #if TARGET_OS_MAC
  37. #endif
  38.  
  39. // global variables for Windows code
  40. #if TARGET_OS_WIN32
  41. extern HWND                ghWnd;                                    // the MDI frame window; this window has the menu bar
  42. extern int                gNumWindowsOpen;
  43. extern LPSTR            gCmdLine;
  44. #endif
  45.  
  46. long                    gMaxMilliSecToUse = 0L;        
  47.  
  48. extern Boolean            gSearchForward;
  49. extern Boolean            gSearchWrap;
  50. extern Boolean            gSearchWithCase;
  51. extern Str255            gSearchText;
  52. extern Str255            gSampleText;
  53.  
  54.  
  55. //////////
  56. //
  57. // InitApplication
  58. // Do any application-specific initialization.
  59. //
  60. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  61. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  62. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  63. //
  64. //////////
  65.  
  66. void InitApplication (UInt32 theStartPhase)
  67. {
  68.     // ***do any start-up activities that should occur before the MDI frame window is created
  69.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  70.         QTText_CopyCStringToPascal(kSearchText, gSearchText);
  71.         QTText_CopyCStringToPascal(kSampleText, gSampleText);
  72.     }    // end of kInitAppPhase_BeforeCreateFrameWindow
  73.  
  74.     // ***do any start-up activities that should occur after the MDI frame window is created
  75.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  76.         
  77. #if TARGET_OS_WIN32
  78.         // on Windows, open as movie documents any files specified on the command line
  79.         DoOpenCommandLineMovies(gCmdLine);                                    
  80. #endif
  81.  
  82.     }    // end of kInitAppPhase_AfterCreateFrameWindow
  83. }
  84.  
  85.  
  86. //////////
  87. //
  88. // StopApplication
  89. // Do any application-specific shut-down.
  90. //
  91. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  92. // *before* any open movie windows are destroyed or *after*.
  93. //
  94. //////////
  95.  
  96. void StopApplication (UInt32 theStopPhase)
  97. {
  98.  
  99. }
  100.  
  101.  
  102. //////////
  103. //
  104. // DoIdle
  105. // Do any processing that can/should occur at idle time.
  106. //
  107. //////////
  108.  
  109. void DoIdle (WindowReference theWindow)
  110. {
  111.     WindowObject         myWindowObject = NULL;
  112.     GrafPtr             mySavedPort;
  113.     
  114.     GetPort(&mySavedPort);
  115.     MacSetPort(GetPortFromWindowReference(theWindow));
  116.     
  117.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  118.     if (myWindowObject != NULL) {
  119.         MovieController        myMC = NULL;
  120.     
  121.         myMC = (**myWindowObject).fController;
  122.         if (myMC != NULL) {
  123.  
  124. #if TARGET_OS_MAC
  125.             // restore the cursor to the arrow
  126.             // if it's outside the front movie window or outside the window's visible region
  127.             if (theWindow == GetFrontMovieWindow()) {
  128.                 Rect    myRect;
  129.                 Point    myPoint;
  130.                 
  131.                 GetMouse(&myPoint);
  132.                 MCGetControllerBoundsRect(myMC, &myRect);
  133.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, GetPortFromWindowReference(theWindow)->visRgn))
  134.                     MacSetCursor(&qd.arrow);
  135.             }
  136. #endif    // TARGET_OS_MAC
  137.         }
  138.     }
  139.  
  140.     MacSetPort(mySavedPort);
  141. }
  142.  
  143.  
  144. //////////
  145. //
  146. // DoUpdateWindow
  147. // Update the specified window.
  148. //
  149. //////////
  150.  
  151. void DoUpdateWindow (WindowReference theWindow, Rect *theRefreshArea)
  152. {
  153.     GrafPtr             mySavedPort;
  154.     
  155.     GetPort(&mySavedPort);
  156.     MacSetPort(GetPortFromWindowReference(theWindow));
  157.     
  158.     BeginUpdate(GetPortFromWindowReference(theWindow));
  159.     
  160.     // draw the movie controller and its movie
  161.     MCDoAction(GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  162.     
  163.     EndUpdate(GetPortFromWindowReference(theWindow));
  164.     MacSetPort(mySavedPort);
  165. }
  166.  
  167.  
  168. //////////
  169. //
  170. // HandleContentClick
  171. // Handle mouse button clicks in the specified window.
  172. //
  173. //////////
  174.  
  175. void HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  176. {
  177.     GrafPtr             mySavedPort;
  178.     
  179.     GetPort(&mySavedPort);
  180.     MacSetPort(GetPortFromWindowReference(theWindow));
  181.     
  182.     // @@@INSERT APPLICATION-SPECIFIC CONTENT CLICKING FUNCTIONALITY HERE
  183.  
  184.     MacSetPort(mySavedPort);
  185. }
  186.  
  187.  
  188. //////////
  189. //
  190. // HandleApplicationKeyPress
  191. // Handle application-specific key presses.
  192. // Returns true if the key press was handled, false otherwise.
  193. //
  194. //////////
  195.  
  196. Boolean HandleApplicationKeyPress (char theCharCode)
  197. {
  198.     Boolean        isHandled = true;
  199.     
  200.     switch (theCharCode) {
  201.     
  202.         // @@@HANDLE APPLICATION-SPECIFIC KEY PRESSES HERE
  203.  
  204.         default:
  205.             isHandled = false;
  206.             break;
  207.     }
  208.  
  209.     return(isHandled);
  210. }
  211.  
  212.  
  213. #if TARGET_OS_MAC
  214. //////////
  215. //
  216. // CreateMovieWindow
  217. // Create a window to display a movie in.
  218. //
  219. //////////
  220.  
  221. WindowRef CreateMovieWindow (Rect *theRect, Str255 theTitle)
  222. {
  223.     WindowRef            myWindow;
  224.         
  225.     myWindow = NewCWindow(NULL, theRect, theTitle, false, noGrowDocProc, (WindowPtr)-1L, true, 0);
  226.     return(myWindow);
  227. }
  228. #endif
  229.  
  230.  
  231. //////////
  232. //
  233. // HandleApplicationMenu
  234. // Handle selections in the application's menus.
  235. //
  236. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  237. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window proc.
  238. // When called from MacOS, theMenuItem is constructed like this:
  239. //     •high-order 8 bits == the Macintosh menu ID (1 thru 256)
  240. //     •low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  241. // In this way, we can simplify the menu-handling code. There are, however, some limitations,
  242. // mainly that the menu item identifiers on Windows must be derived from the Mac values. 
  243. //
  244. //////////
  245.  
  246. void HandleApplicationMenu (UInt16 theMenuItem)
  247. {
  248.     WindowObject        myWindowObject = NULL;
  249.     ApplicationDataHdl    myAppData = NULL;
  250.     MovieController     myMC = NULL;
  251.     Movie                 myMovie = NULL;
  252.     OSErr                myErr = noErr;
  253.     
  254.     myWindowObject = GetWindowObjectFromFrontWindow();
  255.     if (myWindowObject != NULL) {
  256.         myMC = (**myWindowObject).fController;
  257.         myMovie = (**myWindowObject).fMovie;
  258.         myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  259.     }
  260.     
  261.     switch (theMenuItem) {
  262.     
  263.         case IDM_SET_TEXT:
  264.             // put up a dialog box to get a text string
  265.             QTText_SetSearchText();
  266.             break;
  267.                 
  268.         case IDM_FIND_TEXT:
  269.             QTText_FindText(myWindowObject, gSearchText);
  270.             break;
  271.                 
  272.         case IDM_EDIT_TEXT:
  273.             QTText_EditText(myWindowObject);
  274.             break;
  275.                 
  276.         case IDM_SEARCH_FORWARD:
  277.             gSearchForward = true;    
  278.             break;
  279.                 
  280.         case IDM_SEARCH_BACKWARD:
  281.             gSearchForward = false;    
  282.             break;
  283.                 
  284.         case IDM_WRAP_SEARCH:
  285.             gSearchWrap = !gSearchWrap;    
  286.             break;
  287.                 
  288.         case IDM_USE_CASE:
  289.             gSearchWithCase = !gSearchWithCase;    
  290.             break;
  291.                 
  292.         case IDM_ADD_TEXT_TRACK:
  293.             {
  294.                 // add a text track to the specified movie;
  295.                 // for purposes of illustration, we'll add 3 (count 'em!) text strings to the movie,
  296.                 // with each string occupying about one-third of the movie duration
  297.                 
  298.                 Track        myTypeTrack = NULL;
  299.                 Track        myTextTrack = NULL;
  300.                 TimeValue    myMovieDuration = 0;
  301.                 TimeValue    mySampleDuration = 0;
  302.                 char        *myStrings[] = {"Text 1", "Text 2", "Text 3"};
  303.                 short        myFrames[3];
  304.                 Boolean        isChapter = true;
  305.                 
  306.                 myTypeTrack = GetMovieIndTrackType(myMovie, 1, VideoMediaType, movieTrackMediaType);
  307.                 if (myTypeTrack == NULL)
  308.                     break;
  309.                     
  310.                 // get the duration of the movie and the duration of a single frame;
  311.                 // this tells us how many frames fit into one-third of the movie
  312.                 myMovieDuration = GetMovieDuration(myMovie);
  313.                 mySampleDuration = QTUtils_GetFrameDuration(myTypeTrack);
  314.                 
  315.                 myFrames[0] = (myMovieDuration / mySampleDuration) / 3;
  316.                 myFrames[1] = (myMovieDuration / mySampleDuration) / 3;
  317.                 myFrames[2] = (myMovieDuration / mySampleDuration) - (myFrames[0] + myFrames[1]);                
  318.                                 
  319.                 myTextTrack = QTText_AddTextTrack(myMovie, myStrings, myFrames, 3, VideoMediaType, isChapter);
  320.                 if (myTextTrack != NULL) {
  321.  
  322.                     QTText_UpdateMovieAndController(myMC);
  323.  
  324.                     // stamp the movie as dirty and update our saved data
  325.                     (**myWindowObject).fDirty = true;
  326.                     (**myAppData).fMovieHasText = true;
  327.                     (**myAppData).fTextIsChapter = isChapter;
  328.                     (**myAppData).fTextTrack = myTextTrack;
  329.                     (**myAppData).fTextHandler = GetMediaHandler(GetTrackMedia(myTextTrack));
  330.                 }
  331.             }
  332.             break;
  333.                 
  334.         case IDM_CUT_TEXT_TRACK:
  335.             // remove all existing text tracks from the specified movie
  336.             myErr = QTText_RemoveIndTextTrack(myMovie, kAllTextTracks);
  337.             if (myErr == noErr) {
  338.             
  339.                 QTText_UpdateMovieAndController(myMC);
  340.  
  341.                 // stamp the movie as dirty and update our saved data
  342.                 (**myWindowObject).fDirty = true;
  343.                 (**myAppData).fMovieHasText = false;
  344.                 (**myAppData).fTextIsChapter = false;
  345.                 (**myAppData).fTextTrack = NULL;
  346.                 (**myAppData).fTextHandler = NULL;
  347.             }
  348.             break;
  349.                 
  350.         case IDM_CHAPTER_TRACK:
  351.             (**myAppData).fTextIsChapter = !(**myAppData).fTextIsChapter;
  352.             QTText_SetTextTrackAsChapterTrack(myWindowObject, VideoMediaType, (**myAppData).fTextIsChapter);
  353.             break;
  354.             
  355.         default:
  356.             break;
  357.     } // switch (theMenuItem)
  358. }
  359.  
  360.  
  361. //////////
  362. //
  363. // AdjustApplicationMenus
  364. // Adjust state of items in the application's menus.
  365. //
  366. //////////
  367.  
  368. void AdjustApplicationMenus (WindowReference theWindow, MenuReference theMenu)
  369. {
  370.     WindowObject        myWindowObject = NULL; 
  371.     ApplicationDataHdl    myAppData = NULL;
  372.     MovieController     myMC = NULL;
  373.     MenuReference        myMenu;
  374.     
  375. #if TARGET_OS_WIN32
  376.     myMenu = theMenu;
  377. #elif TARGET_OS_MAC
  378.     myMenu = GetMenuHandle(kTestMenu);
  379. #endif
  380.     
  381.     if (theWindow != NULL)
  382.         myWindowObject = GetWindowObjectFromWindow(theWindow);
  383.     
  384.     // assume it's all disabled
  385.     SetMenuItemState(myMenu, IDM_SET_TEXT, kDisableMenuItem);
  386.     SetMenuItemState(myMenu, IDM_FIND_TEXT, kDisableMenuItem);
  387.     SetMenuItemState(myMenu, IDM_EDIT_TEXT, kDisableMenuItem);
  388.     SetMenuItemState(myMenu, IDM_SEARCH_FORWARD, kDisableMenuItem);
  389.     SetMenuItemState(myMenu, IDM_SEARCH_BACKWARD, kDisableMenuItem);
  390.     SetMenuItemState(myMenu, IDM_WRAP_SEARCH, kDisableMenuItem);
  391.     SetMenuItemState(myMenu, IDM_USE_CASE, kDisableMenuItem);
  392.     SetMenuItemState(myMenu, IDM_ADD_TEXT_TRACK, kDisableMenuItem);
  393.     SetMenuItemState(myMenu, IDM_CUT_TEXT_TRACK, kDisableMenuItem);
  394.     SetMenuItemState(myMenu, IDM_CHAPTER_TRACK, kDisableMenuItem);
  395.  
  396.     // set check marks
  397.     SetMenuItemCheck(myMenu, IDM_SEARCH_FORWARD, gSearchForward);
  398.     SetMenuItemCheck(myMenu, IDM_SEARCH_BACKWARD, !gSearchForward);
  399.     SetMenuItemCheck(myMenu, IDM_WRAP_SEARCH, gSearchWrap);
  400.     SetMenuItemCheck(myMenu, IDM_USE_CASE, gSearchWithCase);
  401.     
  402.     if (myWindowObject != NULL) {
  403.         myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(myWindowObject);
  404.         if ((myAppData != NULL) && ((**myAppData).fMovieHasText)) {
  405.             SetMenuItemState(myMenu, IDM_SET_TEXT, kEnableMenuItem);
  406.             SetMenuItemState(myMenu, IDM_FIND_TEXT, kEnableMenuItem);
  407.             SetMenuItemState(myMenu, IDM_EDIT_TEXT, kEnableMenuItem);
  408.             SetMenuItemState(myMenu, IDM_SEARCH_FORWARD, kEnableMenuItem);
  409.             SetMenuItemState(myMenu, IDM_SEARCH_BACKWARD, kEnableMenuItem);
  410.             SetMenuItemState(myMenu, IDM_WRAP_SEARCH, kEnableMenuItem);
  411.             SetMenuItemState(myMenu, IDM_USE_CASE, kEnableMenuItem);
  412.             SetMenuItemState(myMenu, IDM_CHAPTER_TRACK, kEnableMenuItem);
  413.             SetMenuItemState(myMenu, IDM_CUT_TEXT_TRACK, kEnableMenuItem);
  414.             SetMenuItemCheck(myMenu, IDM_CHAPTER_TRACK, (**myAppData).fTextIsChapter);
  415.         } else {
  416.             SetMenuItemState(myMenu, IDM_ADD_TEXT_TRACK, kEnableMenuItem);
  417.         }
  418.     }
  419.     
  420.     // we don't allow creating new files here...
  421. #if TARGET_OS_MAC
  422.     SetMenuItemState(GetMenuHandle(mFile), iNew, kDisableMenuItem);
  423. #endif
  424. }
  425.  
  426.  
  427. //////////
  428. //
  429. // DoApplicationEventLoopAction
  430. // Perform any application-specific event loop actions.
  431. //
  432. // Return true to indicate that we've completely handled the event here, false otherwise.
  433. //
  434. //////////
  435.  
  436. Boolean DoApplicationEventLoopAction (EventRecord *theEvent)
  437. {
  438.     return(false);            // no-op for now
  439. }
  440.  
  441.  
  442. //////////
  443. //
  444. // AddControllerFunctionality
  445. // Configure the movie controller.
  446. //
  447. //////////
  448.  
  449. void AddControllerFunctionality (MovieController theMC)
  450. {
  451.     long            myControllerFlags;
  452.     
  453.     // CLUT table use    
  454.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  455.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  456.  
  457.     // enable keyboard event handling    
  458.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  459.     
  460.     // disable drag support
  461.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  462. }
  463.  
  464.  
  465. //////////
  466. //
  467. // InitApplicationWindowObject
  468. // Do any application-specific initialization of the window object.
  469. //
  470. //////////
  471.  
  472. void InitApplicationWindowObject (WindowObject theWindowObject)
  473. {        
  474.     if (theWindowObject != NULL)
  475.         (**theWindowObject).fAppData = (Handle)QTText_InitWindowData(theWindowObject);
  476. }
  477.  
  478.  
  479. //////////
  480. //
  481. // RemoveApplicationWindowObject
  482. // Do any application-specific clean-up of the window object.
  483. //
  484. //////////
  485.  
  486. void RemoveApplicationWindowObject (WindowObject theWindowObject)
  487. {
  488.     if (theWindowObject != NULL)
  489.         QTText_DumpWindowData(theWindowObject);
  490.     
  491.     // DoDestroyMovieWindow in MacFramework.c or MovieWndProc in WinFramework.c
  492.     // releases the window object itself
  493. }
  494.  
  495.  
  496. //////////
  497. //
  498. // ApplicationMCActionFilterProc 
  499. // Intercept some mc actions for the movie controller.
  500. //
  501. // NOTE: The theRefCon parameter is a handle to a window object record.
  502. //
  503. //////////
  504.  
  505. PASCAL_RTN Boolean ApplicationMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  506. {
  507. #pragma unused(theMC, theParams)
  508.  
  509.     Boolean                isHandled = false;
  510.     WindowObject        myWindowObject = NULL;
  511.     
  512.     myWindowObject = (WindowObject)theRefCon;
  513.     if (myWindowObject == NULL)
  514.         return(isHandled);
  515.         
  516.     switch (theAction) {
  517.     
  518.         // handle window resizing
  519.         case mcActionControllerSizeChanged:
  520.             SizeWindowToMovie(myWindowObject);
  521.             break;
  522.  
  523.         // handle idle events
  524.         case mcActionIdle:
  525.             DoIdle((**myWindowObject).fWindow);
  526.             break;
  527.             
  528.         default:
  529.             break;
  530.             
  531.     }    // switch (theAction)
  532.     
  533.     return(isHandled);    
  534. }
  535.  
  536.  
  537.